package com.glorious.security.extension.mobile;

import com.glorious.api.AppUserFeignClient;
import com.glorious.common.Result;
import com.glorious.common.ResultCode;
import com.glorious.dto.response.appuser.AppUserAuthResponse;
import com.glorious.exception.NormalException;
import com.glorious.security.core.userdetails.user.AppUserDetailsServiceImpl;
import com.glorious.security.extension.wechat.WechatAuthenticationToken;
import lombok.Data;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.HashSet;

/**
 * 手机号密码认证授权提供者
 */
@Data
public class MobileAuthenticationProvider implements AuthenticationProvider {

    private UserDetailsService userDetailsService;
    private AppUserFeignClient appUserFeignClient;

    /**
     * 手机号认证
     *
     * @param authentication
     * @return
     * @throws AuthenticationException
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        MobileAuthenticationToken authenticationToken = (MobileAuthenticationToken) authentication;
        String mobile = (String) authenticationToken.getPrincipal();
        String password = (String) authenticationToken.getCredentials();
        Result<AppUserAuthResponse> appUserAuthResponse = appUserFeignClient.loadUserByMobile(mobile);
        if (null == appUserAuthResponse) {
            throw new NormalException("登录失败");
        }
        if (ResultCode.USER_NOT_EXIST.getCode().equals(appUserAuthResponse.getCode())) {
            throw new NormalException("您未注册");
        }
        AppUserAuthResponse response = appUserAuthResponse.getData();

        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

        boolean matches = passwordEncoder.matches(password, response.getPassword());
        if (!matches) {
            throw new NormalException("密码错误");
        }
        UserDetails userDetails = ((AppUserDetailsServiceImpl) userDetailsService).loadUserByMobile(mobile);
        MobileAuthenticationToken result = new MobileAuthenticationToken(userDetails, new HashSet<>());
        result.setDetails(authentication.getDetails());
        return result;
    }


    @Override
    public boolean supports(Class<?> authentication) {
        return MobileAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
